package com.causelist.main;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.causelist.db.CauseListDAO;
import com.causelist.exception.CauseListException;
import com.causelist.utils.CauseListConstants;
import com.causelist.utils.CauseListUtility;
import com.causelist.vo.CauseVO;

public class CauseList {
	
	static CauseListDAO causeListDAO = null;

	/**
	 * @param args
	 */
	public static void main(String[] args) throws CauseListException{
		// TODO Auto-generated method stub	
		
		ApplicationContext context = new ClassPathXmlApplicationContext(CauseListConstants.BEAN_FILE);		
		causeListDAO = (CauseListDAO) context.getBean(CauseListConstants.CAUSE_LIST_DAO);

		
		File inputFile = new File("filename.txt");
		//File inputFile = new File("C:\\Seetharaman\\Cause List\\causelist_17may.txt");
		
		
		}
	
	
	public void parseInputStream(InputStream is) throws CauseListException
	{

		
		BufferedReader br;
		try {
			br = new BufferedReader(new InputStreamReader(is));
			List<CauseVO> causeList = new ArrayList<CauseVO>();
			CauseVO causeVO = null;
			String jusName = null;
						
			StringBuffer serialNo = new StringBuffer(CauseListConstants.EMPTY_STR);
			StringBuffer caseId = new StringBuffer(CauseListConstants.EMPTY_STR);
			StringBuffer firstPerson = new StringBuffer( CauseListConstants.EMPTY_STR);
			StringBuffer secondPerson = new StringBuffer( CauseListConstants.EMPTY_STR);
			boolean firstRecord = true;
			String line;
		while( (line = br.readLine())!= null)
		{
//			String line = br.readLine();
			
			/*
			 * if the emptyline flag is set to true and the next line begins with a number, then its a new record.
			 * if the emptyline flag is set to true and if the next line does not begin with a number , then its the continuation of the prev record.
			 * remember to reset the emptyLineFlag to false in this case.
			 */
			
			if(null != line)
			{
			  if(CauseListUtility.isEmptyLine(line))
			  {
				  continue;
			  }
			}
			else
			{
				// End Of File
				if(causeVO != null)
				{					
					causeVO.setJusticeName(jusName);
					causeVO.setCaseId(caseId.toString());
					causeVO.setFirstPerson(firstPerson.toString());
					causeVO.setSecondPerson(secondPerson.toString());
					causeList.add(causeVO);
					serialNo = new StringBuffer(CauseListConstants.EMPTY_STR);
					caseId = new StringBuffer(CauseListConstants.EMPTY_STR);
					firstPerson = new StringBuffer(CauseListConstants.EMPTY_STR);
					secondPerson = new StringBuffer(CauseListConstants.EMPTY_STR);
					
				}
				System.out.println("File Parsed Completely");
				List<String> commaSeparatedCauseList = new ArrayList<String>();
				 for(int i=0;i<causeList.size();i++)
				   {
					   
					 CauseVO vo = (CauseVO) causeList.get(i);
					 commaSeparatedCauseList.add((CauseListUtility.trim(CauseListUtility.wrapToSingleLine((vo.getCaseId()))+    CauseListConstants.COMMA+
							 					  CauseListUtility.trim(CauseListUtility.wrapToSingleLine(vo.getFirstPerson()))+CauseListConstants.COMMA+
							 					  CauseListUtility.trim(CauseListUtility.wrapToSingleLine(vo.getSecondPerson()))+CauseListConstants.COMMA+
							 					  CauseListUtility.trim(CauseListUtility.wrapToSingleLine(vo.getJusticeName())))));
				   }	
				
	            CauseList cl = new CauseList();
	            parseCSVListAndInsertToDB(commaSeparatedCauseList);
	            System.exit(0);
/*	            
				try{
					   FileWriter fstream = new FileWriter("out.txt");
					   BufferedWriter out = new BufferedWriter(fstream);
					   
					   for(int i=0;i<causeList.size();i++)
					   {
						   
						 CauseVO vo = (CauseVO) causeList.get(i);
						 out.write((CauseListUtility.trim(CauseListUtility.wrapToSingleLine((vo.getCaseId()))+    CauseListConstants.COMMA+
			 					  CauseListUtility.trim(CauseListUtility.wrapToSingleLine(vo.getFirstPerson()))+CauseListConstants.COMMA+
			 					  CauseListUtility.trim(CauseListUtility.wrapToSingleLine(vo.getSecondPerson()))+CauseListConstants.COMMA+
			 					  CauseListUtility.trim(CauseListUtility.wrapToSingleLine(vo.getJusticeName())))));
						 out.write(CauseListConstants.NEW_LINE);
						 
					   }					   
					   out.close();
					   }
					   catch (Exception e)
					   {
						   throw new CauseListException(e.getMessage());
					   }*/
					 
 				
				//System.exit(0);*/
		}
			
			if(line.contains(CauseListConstants.COMMA) || 
			   line.contains(CauseListConstants.PATTERN_HYPHEN) || 
			   line.contains(CauseListConstants.PATTERN_TILDE) || 
			   line.contains(CauseListConstants.PATTERN_STAR))				
			{
				continue;
			}
			
			/*
			*/
			
			
			if(CauseListUtility.emptyLineFlag && CauseListUtility.isNewRecord(line))
			{
				
				CauseListUtility.emptyLineFlag = false;
				if(!firstRecord)
				{   
					causeVO.setJusticeName(jusName);
					causeVO.setCaseId(caseId.toString());
					causeVO.setFirstPerson(firstPerson.toString());
					causeVO.setSecondPerson(secondPerson.toString());
					causeList.add(causeVO);
				}
				causeVO = new CauseVO();
				serialNo = new StringBuffer(CauseListConstants.EMPTY_STR);
				caseId = new StringBuffer(CauseListConstants.EMPTY_STR);
				firstPerson = new StringBuffer(CauseListConstants.EMPTY_STR);
				secondPerson = new StringBuffer(CauseListConstants.EMPTY_STR);
			}
			/*else
			{
				
			}*/
							
				/*
				   RULE 1 : If the first character of the line is a # , it's the beginning of a new record.
     			   RULE 2 : If the line is complete empty, it is the End of a record.
     			   RULE 3 : Between Rule 1 & Rule 2 , data starting from 9th character is the assumed cause id.
			       RULE 4 : Data Starting from the 32nd character represents the details.
				 */
				
				
				/*
				 * For programming purpose, the columns are named as below:
				 * 
				 *  Column 1 : Serial Number
				 *  Column 2 : Cause Id
				 *  Column 3 : First Person
				 *  Column 4 : Second Person
				 */
			
			if(CauseListUtility.isCourtName(line))
			{
				continue;
			}
			
			// Add Justice Name to Cause List
			if(CauseListUtility.isJusticeName(line))
			{
				//Set Justice Name
				jusName = CauseListUtility.extractJusticeName(line);				 
				continue;
			}
			
					if(CauseListUtility.newRecordFlag)
					{	
						firstRecord = false;// Add court name to Cause List
					}
				
					try
					{
					if( line.length() >  CauseListConstants.SERIAL_NUM_START_INDEX && 
						line.substring(CauseListConstants.SERIAL_NUM_START_INDEX,CauseListUtility.returnSmallerNumber( CauseListConstants.SERIAL_NUM_END_INDEX, line.length())) != null && 
						!line.substring(CauseListConstants.SERIAL_NUM_START_INDEX,CauseListUtility.returnSmallerNumber(CauseListConstants.SERIAL_NUM_END_INDEX, line.length())).trim().equals(CauseListConstants.EMPTY_STR))
					{
						serialNo = serialNo.append(CauseListConstants.NEW_LINE).append(line.substring(CauseListConstants.SERIAL_NUM_START_INDEX,CauseListUtility.returnSmallerNumber(CauseListConstants.SERIAL_NUM_END_INDEX, line.length())).trim());
						
					}
					if( line.length() >  CauseListConstants.CASE_ID_START_INDEX && 
						line.substring(CauseListConstants.SERIAL_NUM_END_INDEX,CauseListUtility.returnSmallerNumber(CauseListConstants.CASE_ID_END_INDEX, line.length())) != null && 
						!line.substring(CauseListConstants.SERIAL_NUM_END_INDEX,CauseListUtility.returnSmallerNumber(CauseListConstants.CASE_ID_END_INDEX, line.length())).trim().equals(CauseListConstants.EMPTY_STR))
					{
						caseId = caseId.append(CauseListConstants.NEW_LINE).append(line.substring(CauseListConstants.SERIAL_NUM_END_INDEX,CauseListUtility.returnSmallerNumber(CauseListConstants.CASE_ID_END_INDEX, line.length())).trim());
					}
					
					if( line.length() >  CauseListConstants.FIRST_PERSON_START_INDEX && 
						line.substring(CauseListConstants.CASE_ID_END_INDEX,CauseListUtility.returnSmallerNumber(CauseListConstants.FIRST_PERSON_END_INDEX, line.length())) != null && 
					    !line.substring(CauseListConstants.CASE_ID_END_INDEX,CauseListUtility.returnSmallerNumber(CauseListConstants.FIRST_PERSON_END_INDEX, line.length())).trim().equals(CauseListConstants.EMPTY_STR) )
					{
						firstPerson = firstPerson.append(CauseListConstants.NEW_LINE).append(line.substring(CauseListConstants.CASE_ID_END_INDEX,CauseListUtility.returnSmallerNumber(CauseListConstants.FIRST_PERSON_END_INDEX, line.length())).trim());
					}
					
					if( line.length() >  CauseListConstants.SECOND_PERSON_START_INDEX && 
						line.substring(CauseListConstants.FIRST_PERSON_END_INDEX,line.length()) != null && 
						!line.substring(CauseListConstants.FIRST_PERSON_END_INDEX,line.length()).trim().equals(CauseListConstants.EMPTY_STR))
					{
						secondPerson = secondPerson.append(CauseListConstants.NEW_LINE).append(line.substring(CauseListConstants.FIRST_PERSON_END_INDEX,line.length()).trim());
					}	
					}
					catch(StringIndexOutOfBoundsException e)
					{
						throw new CauseListException(e.getMessage());
					}
				
		}
		} 
		catch (FileNotFoundException e) 
		{
			throw new CauseListException(e.getMessage());
		} 
		catch (IOException e)
		{
			throw new CauseListException(e.getMessage());
		}
		catch(NullPointerException e)
		{
			throw new CauseListException(e.getMessage());
		}
		

		
	}
	
	public void parseCSVListAndInsertToDB(List<String> inputCauseList) throws CauseListException
	{
		List<String[]> arrList = new ArrayList<String[]>();
		for(int i=0;i<inputCauseList.size();i++)
		{
			arrList.add(((String)inputCauseList.get(i)).split(CauseListConstants.COMMA));
		}
		causeListDAO.insertCauseDetails(arrList);
	}
	
	}
